import sys
from pyglet import clock
from pyglet.event import EVENT_HANDLED, EVENT_UNHANDLED
from pyglet.window import key
from pyglet.gl import *
from pyglet import media

import mode, config, engine, squirtle, hud

from common import *
from constants import *
from data import load_sound, load_song

class StartMode (mode.Mode):
    name = 'start'

    def __init__(self):
        super(StartMode, self).__init__()

    def init(self):
        self.player = player = media.Player()
        player.eos_action = player.EOS_LOOP
        player.queue(load_song('notexact - halfpipe_II.mp3'))
        player.play()

    def tick(self):
        self.control.switch_handler('level_enter', 1)

class LevelEnter (mode.Mode):
    name = 'level_enter'
    delay = 120

    def __init__(self, levelno, init_score = 0):
        super(LevelEnter, self).__init__()
        self.levelno = levelno
        self.timer = 0
        self.label_x = 1600
        self.load_x = 1600
        self.init_score = init_score

    def init(self):
        self.text = pyglet.text.Label(text = 'Level %s' % self.levelno, font_name = 'DejaVuSans', font_size = 48,
                anchor_x = 'center', anchor_y = 'center', x = 0, y = 0, color = (0, 0, 0, 255))
        self.loading = pyglet.text.Label(text = 'Loading', font_name = 'DejaVuSans', font_size = 36,
                anchor_x = 'center', anchor_y = 'center', x = 0, y = 0, color = (0, 0, 0, 255))

        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        w = self.window.width / 2
        h = self.window.height / 2
        gluOrtho2D(-w, w, -h, h)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glClearColor(1, 1, 1, 1)

    def tick(self):
        self.timer += 1
        if self.timer < self.delay / 3:
            self.label_x = (40 - self.timer) ** 2
        elif self.timer < 2 * self.delay / 3:
            self.label_x = 0
        elif self.timer < self.delay:
            self.label_x = -(self.timer - 80) ** 2
            self.load_x = (self.delay - self.timer) ** 2
        else:
            self.control.switch_handler('level', engine.Level(self.levelno, self.init_score))

    def on_draw(self):
        self.window.clear()
        glLoadIdentity()
        glTranslatef(self.label_x, 0, 0)
        self.text.draw()
        glLoadIdentity()
        glTranslatef(self.load_x, 0, 0)
        self.loading.draw()

class ThankYou (mode.Mode):
    name = 'thankyou'
    delay = 120

    def __init__(self, final_score):
        super(ThankYou, self).__init__()
        self.final_score = final_score
        self.label_x = 1600
        self.score_x = 1600
        self.timer = 0

    def init(self):
        self.text = pyglet.text.Label(text = 'Thank you', font_name = 'DejaVuSans', font_size = 48,
                anchor_x = 'center', anchor_y = 'center', x = 0, y = 0, color = (0, 0, 0, 255))
        self.score = pyglet.text.Label(text = 'Score: %05d' % self.final_score, font_name = 'DejaVuSans', font_size = 24,
                anchor_x = 'center', anchor_y = 'center', x = 0, y = 0, color = (0, 0, 0, 255))

        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        w = self.window.width / 2
        h = self.window.height / 2
        gluOrtho2D(-w, w, -h, h)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glClearColor(1, 1, 1, 1)

    def tick(self):
        self.timer += 1
        if self.timer < 60:
            self.label_x = (60 - self.timer) ** 2
        elif self.timer < 120:
            self.label_x = 0
        elif self.timer < 180:
            self.label_x = -(self.timer - 120) ** 2
            self.score_x = (180 - self.timer) ** 2
        elif self.timer < 240:
            self.score_x = 0
        else:
            print 'Thank you for playing.'
            print 'Your final score is:', self.final_score
            sys.exit()

    def on_draw(self):
        self.window.clear()
        glLoadIdentity()
        glTranslatef(self.label_x, 0, 0)
        self.text.draw()
        glLoadIdentity()
        glTranslatef(self.score_x, 0, 0)
        self.score.draw()

class ScoreMode (mode.Mode):
    name = 'score'

    curtain_time = 60.

    def __init__(self, level):
        super(ScoreMode, self).__init__()
        self.level = level
        self.frame = 0

    def init(self):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluOrtho2D(0, 1, 0, 1)
        glMatrixMode(GL_MODELVIEW)
        self.sound = load_sound('score.wav')

        self.t_score = pyglet.text.Label(text = '00000', font_name = 'DejaVuSans', font_size = 48,
                x = 0, y = 15, anchor_x = 'center', color = (0, 0, 0, 255))
        self.t_power = pyglet.text.Label(text = 'Power bonus:', font_name = 'DejaVuSans', font_size = 24,
                x = -200, y = 300, color = (0, 0, 0, 255))
        self.t_time = pyglet.text.Label(text = 'Time bonus:', font_name = 'DejaVuSans', font_size = 24,
                x = -200, y = 200, color = (0, 0, 0, 255))

        self.score = self.level.ball.score

    def set_pixel_mode(self):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        w = self.window.width / 2
        h = self.window.height
        gluOrtho2D(-w, w, 0, h)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glClearColor(1, 1, 1, 1)

    def tick(self):
        self.frame += 1
        if self.frame < self.curtain_time:
            return

    def draw_curtain(self):
        b = self.frame / self.curtain_time
        glColor4f(1, 1, 1, b)
        glBegin(GL_QUADS)
        glVertex2f(0, 0)
        glVertex2f(0, 1)
        glVertex2f(1, 1)
        glVertex2f(1, 0)
        glEnd()

    def update_labels(self):
        ball = self.level.ball
        self.t_power.text = 'Power bonus: ' + '- ' * ball.power
        self.t_time.text = 'Time bonus: %d' % self.level.before_par
        self.t_score.text = '%05d' % self.score

    def tick(self):
        self.frame += 1
        ball = self.level.ball
        if self.score < ball.score:
            self.score += max(1, (ball.score - self.score) / 10.)
        self.update_labels()

    def do_score(self, dt):
        ball = self.level.ball

        if ball.power > 0:
            ball.power -= 1
            ball.score += POWER_SCORE
            self.sound.play()
        elif self.level.before_par > 0:
            self.level.before_par -= 1
            ball.score += PAR_SCORE
            self.sound.play()
        else:
            clock.unschedule(self.do_score)
            if self.level.levelno < 2:
                self.control.switch_handler('level_enter', self.level.levelno + 1, ball.score)
            else:
                self.control.switch_handler('thankyou', ball.score)
            
        
        self.update_labels()

    def on_draw(self):
        if self.frame < 50:
            self.draw_curtain()
        elif self.frame == 50:
            self.set_pixel_mode()
            clock.schedule_interval_soft(self.do_score, .3)
        else:
            self.window.clear()
            self.t_power.draw()
            self.t_time.draw()
            self.t_score.draw()

class LevelMode (mode.Mode):
    name = 'level'

    def __init__(self, level):
        print 'level', level
        super(LevelMode, self).__init__()
        self.level = level

    def init(self):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        aspect = float(self.window.width) / self.window.height
        gluOrtho2D(0, aspect, 0, 1)
        glMatrixMode(GL_MODELVIEW)
        squirtle.setup_gl()
        glClearColor(1, 1, 1, 1)
        glLineWidth(5)
        self.hud = hud.HUD(self.window, self.level, self.level.ball)

    def tick(self):
        ball = self.level.ball
        ball.reset()
        if self.keys[key.DOWN]:
            ball.shift_down()
        if self.keys[key.UP]:
            ball.shift_up()
        if self.keys[key.LEFT]:
            ball.roll_left()
        if self.keys[key.RIGHT]:
            ball.roll_right()

        self.level.think()
        if self.level.completed:
            self.control.switch_handler('score', self.level)
        
    def on_draw(self):
        self.window.clear()
        glLoadIdentity()
        self.level.render()
        self.hud.render()

        #self.control.switch_handler('score', self.level)

    def on_key_press(self, sym, mods):
        if sym == key.R:
            self.control.switch_handler('level_enter', self.level.levelno)

